﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Arch.EF.Services;
using Arch.IoC;
using Arch.Poc.Services.Contracts;
using Arch.Samples.NTierWPF.Services;
using Arch.Services.ErrorHandling;
using Microsoft.Practices.Unity;
using Arch.Data;
using System.Data.Objects;
using Arch.Poc.Data;
using Arch.Web.IoC;
using System.Configuration;
using Microsoft.Practices.Unity.InterceptionExtension;
using Arch.Poc.Model;
using Arch.Poc.Services;
using Arch.Intercep.CallHandlers;
using Arch.Intercep;

namespace Arch.Poc.Mvc
{
    public class DependencyContainer : ServerDependencyContainer
    {
        public override void RegisterTypes(IUnityContainer container)
        {
            //Register Repository mapping and ObjectContext creation
            container
                .RegisterType(typeof (IRepository<>), typeof (Repository<>))
                .RegisterType<ObjectContext, ObjectContext>(
                    new PerRequestLifetimeManager<ObjectContext>(),
                    new InjectionFactory(
                        c =>
                            {
                                var context =
                                    new ObjectContext(ConfigurationManager.ConnectionStrings["Arch"].ToString());
                                context.ContextOptions.ProxyCreationEnabled = true;
                                context.ContextOptions.LazyLoadingEnabled = true;
                                context.MetadataWorkspace.LoadFromAssembly(typeof (Todo).Assembly);
                                return context;
                            }))
                ;

            //Register repository interception
            ConfigureRepositoryInterception(
                container.Configure<Interception>()
                .SetDefaultInterceptorFor(typeof(Repository<>), new VirtualMethodInterceptor()));

            //Register Services and their interceptors
            AutoRegisterTypes(container, typeof (IService<>),
                              GetLayerTypes(typeof (EntityService<>), typeof (TodoService).Assembly),
                              (i, t) => container.Configure<Interception>()
                                       .SetDefaultInterceptorFor(typeof(TodoService), new VirtualMethodInterceptor())
                                       .AddPolicy("FaultHandling").AddCallHandler(new ExceptionToFaultHandler()));

            //Override the default interceptor manager :
            //container.RegisterInstance<IInterceptorManager>(new DefaultInterceptorManager());

            //Override the default faultcontracts mapped :
            //container.RegisterInstance<IEnumerable<IExceptionToFaultHandler>>(new IExceptionToFaultHandler[] { new ValidationExceptionToFaultHandler() });
        }
    }
}